package cn.sprouting.tool;

import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.sprouting.model.User;
import cn.sprouting.model.common.Constant;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 随机生成名字
 * @Date 创建时间： 2021/11/3. 16:50
 * @Author ：LX
 * 地点：长沙麓谷
 * 备注说明：
 */
@Slf4j
public class RandomNameTool {

    /**
     * 姓氏
     */
    private static final String[] FIRST_NAMES = new String[] { "李", "王", "张",
            "刘", "陈", "杨", "黄", "赵", "周", "吴", "徐", "孙", "朱", "马", "胡", "郭", "林",
            "何", "高", "梁", "郑", "罗", "宋", "谢", "唐", "韩", "曹", "许", "邓", "萧", "冯",
            "曾", "程", "蔡", "彭", "潘", "袁", "於", "董", "余", "苏", "叶", "吕", "魏", "蒋",
            "田", "杜", "丁", "沈", "姜", "范", "江", "傅", "钟", "卢", "汪", "戴", "崔", "任",
            "陆", "廖", "姚", "方", "金", "邱", "夏", "谭", "韦", "贾", "邹", "石", "熊", "孟",
            "秦", "阎", "薛", "侯", "雷", "白", "龙", "段", "郝", "孔", "邵", "史", "毛", "常",
            "万", "顾", "赖", "武", "康", "贺", "严", "尹", "钱", "施", "牛", "洪", "龚", };

    /**
     * 女生姓名
     */
    private static String GIRL = "秀娟英华慧巧美娜静淑惠珠翠雅芝玉萍红娥玲芬芳燕彩春菊兰凤洁梅琳素云莲真环雪荣爱妹霞香月莺媛艳瑞凡佳嘉琼勤珍贞莉桂娣叶璧璐娅琦晶妍茜秋珊莎锦黛青倩婷姣婉娴瑾颖露瑶怡婵雁蓓纨仪荷丹蓉眉君琴蕊薇菁梦岚苑婕馨瑗琰韵融园艺咏卿聪澜纯毓悦昭冰爽琬茗羽希宁欣飘育滢馥筠柔竹霭凝晓欢霄枫芸菲寒伊亚宜可姬舒影荔枝思丽 ";
    /**
     * 男生姓名
     */
    private static String BOY = "伟刚勇毅俊峰强军平保东文辉力明永健世广志义兴良海山仁波宁贵福生龙元全国胜学祥才发武新利清飞彬富顺信子杰涛昌成康星光天达安岩中茂进林有坚和彪博诚先敬震振壮会思群豪心邦承乐绍功松善厚庆磊民友裕河哲江超浩亮政谦亨奇固之轮翰朗伯宏言若鸣朋斌梁栋维启克伦翔旭鹏泽晨辰士以建家致树炎德行时泰盛雄琛钧冠策腾楠榕风航弘";

    /**
     * 英文名字基础字典
     */
    private static String[] FIRST_NAMES_ENGLISH = {
            "Aaron", "Abel", "Abraham", "Adam", "Adrian", "Aidan", "Alva", "Alex", "Alexander", "Alan", "Albert", "Alfred", "Andrew", "Andy", "Angus", "Anthony", "Apollo", "Arnold", "Arthur", "August", "Austin", "Ben", "Benjamin", "Bert", "Benson", "Bill", "Billy", "Blake", "Bob", "Bobby", "Brad", "Brandon", "Brant", "Brent", "Brian", "Brown", "Bruce", "Caleb", "Cameron", "Carl", "Carlos", "Cary", "Caspar", "Cecil", "Charles", "Cheney", "Chris", "Christian", "Christopher", "Clark", "Cliff", "Cody", "Cole", "Colin", "Cosmo", "Daniel", "Denny", "Darwin", "David", "Dennis", "Derek", "Dick", "Donald", "Douglas", "Duke", "Dylan", "Eddie", "Edgar", "Edison", "Edmund", "Edward", "Edwin", "Elijah", "Elliott", "Elvis", "Eric", "Ethan", "Eugene", "Evan", "Enterprise", "Ford", "Francis", "Frank", "Franklin", "Fred", "Gabriel", "Gaby", "Garfield", "Gary", "Gavin", "Geoffrey", "George", "Gino", "Glen", "Glendon", "Hank", "Hardy", "Harrison", "Harry", "Hayden", "Henry", "Hilton", "Hugo", "Hunk", "Howard", "Henry", "Ian", "Ignativs", "Ivan", "Isaac", "Isaiah", "Jack", "Jackson", "Jacob", "James", "Jason", "Jay", "Jeffery", "Jerome", "Jerry", "Jesse", "Jim", "Jimmy", "Joe", "John", "Johnny", "Jonathan", "Jordan", "Jose", "Joshua", "Justin", "Keith", "Ken", "Kennedy", "Kenneth", "Kenny", "Kevin", "Kyle", "Lance", "Larry", "Laurent", "Lawrence", "Leander", "Lee", "Leo", "Leonard", "Leopold", "Leslie", "Loren", "Lori", "Lorin", "Louis", "Luke", "Marcus", "Marcy", "Mark", "Marks", "Mars", "Marshal", "Martin", "Marvin", "Mason", "Matthew", "Max", "Michael", "Mickey", "Mike", "Nathan", "Nathaniel", "Neil", "Nelson", "Nicholas", "Nick", "Noah", "Norman", "Oliver", "Oscar", "Owen", "Patrick", "Paul", "Peter", "Philip", "Phoebe", "Quentin", "Randall", "Randolph", "Randy", "Ray", "Raymond", "Reed", "Rex", "Richard", "Richie", "Riley", "Robert", "Robin", "Robinson", "Rock", "Roger", "Ronald", "Rowan", "Roy", "Ryan", "Sam", "Sammy", "Samuel", "Scott", "Sean", "Shawn", "Sidney", "Simon", "Solomon", "Spark", "Spencer", "Spike", "Stanley", "Steve", "Steven", "Stewart", "Stuart", "Terence", "Terry", "Ted", "Thomas", "Tim", "Timothy", "Todd", "Tommy", "Tom", "Thomas", "Tony", "Tyler", "Ultraman", "Ulysses", "Van", "Vern", "Vernon", "Victor", "Vincent", "Warner", "Warren", "Wayne", "Wesley", "William", "Willy", "Zack", "Zachary", "Abigail", "Abby", "Ada", "Adelaide", "Adeline", "Alexandra", "Ailsa", "Aimee", "Alexis", "Alice", "Alicia", "Alina", "Allison", "Alyssa", "Amanda", "Amy", "Amber", "Anastasia", "Andrea", "Angel", "Angela", "Angelia", "Angelina", "Ann", "Anna", "Anne", "Annie", "Anita", "Ariel", "April", "Ashley", "Audrey", "Aviva", "Barbara", "Barbie", "Beata", "Beatrice", "Becky", "Bella", "Bess", "Bette", "Betty", "Blanche", "Bonnie", "Brenda", "Brianna", "Britney", "Brittany", "Camille", "Candice", "Candy", "Carina", "Carmen", "Carol", "Caroline", "Carry", "Carrie", "Cassandra", "Cassie", "Catherine", "Cathy", "Chelsea", "Charlene", "Charlotte", "Cherry", "Cheryl", "Chloe", "Chris", "Christina", "Christine", "Christy", "Cindy", "Claire", "Claudia", "Clement", "Cloris", "Connie", "Constance", "Cora", "Corrine", "Crystal", "Daisy", "Daphne", "Darcy", "Dave", "Debbie", "Deborah", "Debra", "Demi", "Diana", "Dolores", "Donna", "Dora", "Doris", "Edith", "Editha", "Elaine", "Eleanor", "Elizabeth", "Ella", "Ellen", "Ellie", "Emerald", "Emily", "Emma", "Enid", "Elsa", "Erica", "Estelle", "Esther", "Eudora", "Eva", "Eve", "Evelyn", "Fannie", "Fay", "Fiona", "Flora", "Florence", "Frances", "Frederica", "Frieda", "Flta", "Gina", "Gillian", "Gladys", "Gloria", "Grace", "Grace", "Greta", "Gwendolyn", "Hannah", "Haley", "Hebe", "Helena", "Hellen", "Henna", "Heidi", "Hillary", "Ingrid", "Isabella", "Ishara", "Irene", "Iris", "Ivy", "Jacqueline", "Jade", "Jamie", "Jane", "Janet", "Jasmine", "Jean", "Jenna", "Jennifer", "Jenny", "Jessica", "Jessie", "Jill", "Joan", "Joanna", "Jocelyn", "Joliet", "Josephine", "Josie", "Joy", "Joyce", "Judith", "Judy", "Julia", "Juliana", "Julie", "June", "Karen", "Karida", "Katherine", "Kate", "Kathy", "Katie", "Katrina", "Kay", "Kayla", "Kelly", "Kelsey", "Kimberly", "Kitty", "Lareina", "Lassie", "Laura", "Lauren", "Lena", "Lydia", "Lillian", "Lily", "Linda", "lindsay", "Lisa", "Liz", "Lora", "Lorraine", "Louisa", "Louise", "Lucia", "Lucy", "Lucine", "Lulu", "Lydia", "Lynn", "Mabel", "Madeline", "Maggie", "Mamie", "Manda", "Mandy", "Margaret", "Mariah", "Marilyn", "Martha", "Mavis", "Mary", "Matilda", "Maureen", "Mavis", "Maxine", "May", "Mayme", "Megan", "Melinda", "Melissa", "Melody", "Mercedes", "Meredith", "Mia", "Michelle", "Milly", "Miranda", "Miriam", "Miya", "Molly", "Monica", "Morgan", "Nancy", "Natalie", "Natasha", "Nicole", "Nikita", "Nina", "Nora", "Norma", "Nydia", "Octavia", "Olina", "Olivia", "Ophelia", "Oprah", "Pamela", "Patricia", "Patty", "Paula", "Pauline", "Pearl", "Peggy", "Philomena", "Phoebe", "Phyllis", "Polly", "Priscilla", "Quentina", "Rachel", "Rebecca", "Regina", "Rita", "Rose", "Roxanne", "Ruth", "Sabrina", "Sally", "Sandra", "Samantha", "Sami", "Sandra", "Sandy", "Sarah", "Savannah", "Scarlett", "Selma", "Selina", "Serena", "Sharon", "Sheila", "Shelley", "Sherry", "Shirley", "Sierra", "Silvia", "Sonia", "Sophia", "Stacy", "Stella", "Stephanie", "Sue", "Sunny", "Susan", "Tamara", "Tammy", "Tanya", "Tasha", "Teresa", "Tess", "Tiffany", "Tina", "Tonya", "Tracy", "Ursula", "Vanessa", "Venus", "Vera", "Vicky", "Victoria", "Violet", "Virginia", "Vita", "Vivian"
    };



    /**
     * 生成真实姓名，注意，该方法将获取已有的字典，消耗比较大，应该尽量一次性获取
     * @param num 生成数量，不能超过2W条
     * @param sex 指定性别，不指定则随便生成 {@link Constant.SexInteger}
     * @return
     */
    public static List<User> getRealName(Integer num, Integer sex){
        if (num == null || num < 1){
            num = 1;
        }

        String txt = ResourceUtil.readUtf8Str("realName.txt");
        String[] array = txt.split("\r\n");
        List<User> userList = new ArrayList<>();
        for (String row : array){
            String[] split = row.split(",");
            String sexChinese = split[1];
            User user = new User();
            user.setName(split[0]);
            if ("男".equals(sexChinese)){
                user.setSex(Constant.SexInteger.MALE);
            } else {
                user.setSex(Constant.SexInteger.FEMALE);
            }

            // 性别过滤
            if (sex != null){
                if (user.getSex().equals(sex)){
                    userList.add(user);
                }

            } else {
                userList.add(user);
            }
        }

        if (userList.size() == 0){
            return null;
        }
        if (num > userList.size()){
            num = userList.size();
        }

        return RandomUtil.randomEleList(userList, num);
    }


    /**
     * 随机生成昵称
     * @param min 昵称最小长度，不能小于2
     * @param max 昵称最大长度，不能小于3
     * @return
     */
    public static String getChineseNickName(int min, int max){
        if (min < 2){
            min = 2;
        }
        if (max < 3){
            max = 3;
        }

        int index = RandomUtil.randomInt(1, 11);
        if (index % 2 == 0) {
            String txt = ResourceUtil.readUtf8Str("femaleName.txt");
            String[] array = txt.split("\r\n");
            List<String> list = Arrays.asList(array);

            if (list.size() < min){
                min = list.size();
            }
            if (list.size() < max){
                max = list.size();
            }

            //女性名称常用字
            List<String> randomEleList = RandomUtil.randomEleList(list, RandomUtil.randomInt(min, max));
            return StrUtil.join("", randomEleList);

        } else {
            String txt = ResourceUtil.readUtf8Str("maleName.txt");
            String[] array = txt.split("\r\n");
            List<String> list = Arrays.asList(array);

            if (list.size() < min){
                min = list.size();
            }
            if (list.size() < max){
                max = list.size();
            }

            //男性名称常用字
            List<String> randomEleList = RandomUtil.randomEleList(list, RandomUtil.randomInt(min, max));
            return StrUtil.join("", randomEleList);
        }
    }

    /**
     * 随机生成英文昵称
     * @param min 最小长度，不能低于4
     * @param max 最大长度，不能低于4
     * @return
     */
    public static String getEnglishNickName(int min, int max){
        if (min < 4){
            min = 4;
        }
        if (max < 4){
            max = 4;
        }

        // 随机大写字母
        String start = RandomUtil.randomString(RandomUtil.BASE_CHAR, 1).toUpperCase();
        int index = RandomUtil.randomInt(min, max);
        String end = RandomUtil.randomString(RandomUtil.BASE_CHAR, index).toLowerCase();
        return start + end;
    }

    /**
     * 随机生成英文名称
     *   注意，该方法是有字典的，故而，数据量大了之后，还是可能出现重复
     * @param num 生成数量
     * @return
     */
    public static List<String> getNameEnglish(Integer num){
        List<String> list = Arrays.asList(FIRST_NAMES_ENGLISH);
        return RandomUtil.randomEleList(list, num);
    }

    /**
     * 随机生成一个英文名称
     * 注意，该方法是有字典的，故而，数据量大了之后，还是可能出现重复
     * @return
     */
    public static String getNameEnglish(){
        return getNameEnglish(1).get(0);
    }

    /**
     * 生成姓名
     * @param num 生成数量
     * @param sex 性别，不指定则随机 {@link cn.sprouting.model.common.Constant.Sex}
     * @return
     */
    public static List<String> getName(Integer num, Constant.Sex sex){
        if (num == null || num < 1){
            num = 1;
        }
        StringBuilder name = new StringBuilder();
        if (Constant.Sex.FEMALE == sex){
            name.append(GIRL);
        } else if (Constant.Sex.MALE == sex){
            name.append(BOY);
        } else {
            name.append(GIRL);
            name.append(BOY);
        }

        // 最终生成的名字
        List<String> saveList = new ArrayList<>();
        for (int i = 0; i < num; i ++){
            // 名字长度
            int length = RandomUtil.randomInt(1, 3);
            String str = RandomUtil.randomEle(FIRST_NAMES) + RandomUtil.randomString(name.toString(), length);
            saveList.add(str);
        }

        return saveList;
    }

    /**
     * 生成姓名
     * @param num 生成数量
     * @return
     */
    public static List<String> getName(Integer num){
        return getName(num, null);
    }

    /**
     * 生成一个姓名
     * @return
     */
    public static String getName(){
        return getName(1, null).get(0);
    }

    /**
     * 批量生成男性姓名
     * @param num 生成数量
     * @return
     */
    public static List<String> getNameBoy(Integer num){
        return getName(num, Constant.Sex.MALE);
    }

    /**
     * 生成一个男性姓名
     * @return
     */
    public static String getNameBoy(){
        return getName(1, Constant.Sex.MALE).get(0);
    }

    /**
     * 批量生成女性姓名
     * @param num 生成数量
     * @return
     */
    public static List<String> getNameGirl(Integer num){
        return getName(num, Constant.Sex.FEMALE);
    }

    /**
     * 生成一个女性姓名
     * @return
     */
    public static String getNameGirl(){
        return getName(1, Constant.Sex.FEMALE).get(0);
    }

}
